#include <iostream>
#include <string>
#include <cstdlib>
#include <getopt.h>
#include "include/generator.h"
#include "include/CL_compiler.h"
using namespace std;

static bool verbose;

void usage()
{
    cerr << "\n"
"usage: clcalc \n"
"       [--expression OR -e expression to integrate]\n"
"       [--resolution OR -r resolution]\n"
"       [--bounds OR -b start/stop value pair (start,stop)]\n"
"       [--verbose OR -v verbose]\n"
"       [--help OR -h this message]\n"
"   example: clcalc -e 6+23x -r .000005 -b -2.5|17\n";
}

int main(int argc, char *argv[])
{
    op ops;
    verbose = false;
    double result;
    int opt_index;
    int opt;

    const char *options = "e:r:b:v";
    struct option long_options[] =
    {
        {"expression", 1, 0, 'e'},
        {"resolution", 1, 0, 'r'},
        {"bounds", 1, 0, 'b'},
        {"verbose", 0, 0, 'v'},
        {"help", 0, 0, 'h'},
        {0, 0, 0, 0}
    };

    string tmps;
    size_t bar;

    while((opt = getopt_long(argc, argv, options, long_options, &opt_index)) != EOF){
        switch(opt){
        case 'e':
            ops.expression = optarg;
            break;
        case 'r':
            if((ops.size = atof(optarg)) == 0){
                cerr << "resolution may not be 0" << endl;
                return -1;
            }
            break;
        case 'b':
            tmps = optarg;
            bar = tmps.find(",");
            ops.bounds.first = atof(tmps.substr(0, bar).c_str());
            ops.bounds.second = atof(tmps.substr(bar + 1).c_str());
            break;
        case 'v':
            verbose = true;
            break;
        case 'h':
            usage();
            return 0;
        default:
            cerr << "unkown option: " << opt << endl;
            usage();
            return -1;
        }

    }

    //call main constructors
    generator mygen(&ops);
    CL_compiler mycomp("solver_kernels.cl");

    //call compute() and output answer
    result = mycomp.compute(ops);
    cout << fixed << result << endl;

    //call all deconstructors
    mygen.~generator();
    mycomp.~CL_compiler();

    return 0;
}
